<template>
  <a-flex class="encryptionBaseBox" vertical="true" gap="middle">
    <a-flex class="encryptionTopBox" vertical="true" gap="middle">
      <a-menu v-model:selectedKeys="selectedAlgorithm" mode="horizontal">
        <a-menu-item v-for="field in algorithms" :key="field">
          {{ field }}
        </a-menu-item>
      </a-menu>
      <a-textarea v-model:value="inputText" placeholder="输入明文/密文" style="height: 130px;max-height: 300px"/>
      <a-input
        v-if="selectedAlgorithm[0] && requiresKeyAlgorithms.includes(selectedAlgorithm[0])"
        v-model:value="keyInput"
        placeholder="输入密钥（如AES需16/24/32字节，DES需8字节）"
      />
    </a-flex>

    <!-- 新增中间按钮区域 -->
    <a-flex gap="middle">
      <a-button type="primary" @click="handleEncrypt">加密</a-button>
      <!-- 新增条件渲染 -->
      <a-button
        v-if="selectedAlgorithm[0] && supportsDecryptionAlgorithms.includes(selectedAlgorithm[0])"
        type="primary"
        @click="handleDecrypt"
      >
        解密
      </a-button>
      <a-button type="primary" @click="swapInputs">输入输出互换</a-button>
    </a-flex>
    <a-flex flex="1" vertical="true">
      <a-textarea style="height: 100%;resize: none !important;" v-model:value="outputText" placeholder="加密结果将显示在此处"/>
    </a-flex>
  </a-flex>
</template>

<script setup>
import { ref } from 'vue'
import CryptoJS from 'crypto-js'

// 新增支持解密的算法列表
const supportsDecryptionAlgorithms = [
  'AES-ECB', 'AES-CBC', 'DES-ECB', 'DES-CBC',
  'RSA-OAEP', 'RSA-PKCS1', 'Base64'
]

const algorithms = [
  'MD5', 'SHA1', 'SHA256', 'SHA384', 'SHA512',
  'AES-ECB', 'AES-CBC', 'DES-ECB', 'DES-CBC',
  'RSA-OAEP', 'RSA-PKCS1',
  'Base64'
]

const requiresKeyAlgorithms = [
  'AES-ECB', 'AES-CBC', 'DES-ECB', 'DES-CBC',
  'RSA-OAEP', 'RSA-PKCS1'
]

const selectedAlgorithm = ref([algorithms[0]])
const inputText = ref('')
const outputText = ref('')
const keyInput = ref('')

const handleEncrypt = () => {
  if (!inputText.value || !selectedAlgorithm.value.length) return

  const currentAlgorithm = selectedAlgorithm.value[0]
  let encrypted

  switch (currentAlgorithm) {
    case 'MD5':
      encrypted = CryptoJS.MD5(inputText.value).toString()
      break
    case 'SHA1':
      encrypted = CryptoJS.SHA1(inputText.value).toString()
      break
    case 'SHA256':
      encrypted = CryptoJS.SHA256(inputText.value).toString()
      break
    case 'SHA384':
      encrypted = CryptoJS.SHA384(inputText.value).toString()
      break
    case 'SHA512':
      encrypted = CryptoJS.SHA512(inputText.value).toString()
      break
    case 'AES-ECB':
      const key = CryptoJS.enc.Utf8.parse(keyInput.value)
      encrypted = CryptoJS.AES.encrypt(inputText.value, key, { mode: CryptoJS.mode.ECB }).toString()
      break
    case 'AES-CBC':
      const iv = CryptoJS.enc.Utf8.parse('1234567812345678')
      const aesKey = CryptoJS.enc.Utf8.parse(keyInput.value)
      encrypted = CryptoJS.AES.encrypt(inputText.value, aesKey, { iv, mode: CryptoJS.mode.CBC }).toString()
      break
    case 'DES-ECB':
      encrypted = CryptoJS.DES.encrypt(inputText.value, keyInput.value, { mode: CryptoJS.mode.ECB }).toString() // 直接使用字符串密钥（DES可接受）
      break

    // 新增Base64编码处理
    case 'Base64':
      encrypted = CryptoJS.enc.Base64.stringify(
        CryptoJS.enc.Utf8.parse(inputText.value)
      )
      break

    default:
      encrypted = '未实现该算法'
  }

  outputText.value = encrypted
}

// 新增解密函数
const handleDecrypt = () => {
  if (!inputText.value || !selectedAlgorithm.value.length) return

  const currentAlgorithm = selectedAlgorithm.value[0]
  let decrypted

  switch (currentAlgorithm) {
    case 'MD5':
    case 'SHA1':
    case 'SHA256':
    case 'SHA384':
    case 'SHA512':
      decrypted = `${currentAlgorithm}是哈希算法，无法解密`
      break
    case 'AES-ECB':
      const key = CryptoJS.enc.Utf8.parse(keyInput.value)
      decrypted = CryptoJS.AES.decrypt(inputText.value, key, { mode: CryptoJS.mode.ECB })
        .toString(CryptoJS.enc.Utf8)
      break
    case 'AES-CBC':
      const iv = CryptoJS.enc.Utf8.parse('1234567812345678')
      const aesKey = CryptoJS.enc.Utf8.parse(keyInput.value)
      decrypted = CryptoJS.AES.decrypt(inputText.value, aesKey, { iv, mode: CryptoJS.mode.CBC })
        .toString(CryptoJS.enc.Utf8)
      break
    case 'DES-ECB':
      const desKey = CryptoJS.enc.Utf8.parse(keyInput.value)
      decrypted = CryptoJS.DES.decrypt(inputText.value, desKey, { mode: CryptoJS.mode.ECB })
        .toString(CryptoJS.enc.Utf8)
      break
    case 'Base64':
      try {
        const bytes = CryptoJS.enc.Base64.parse(inputText.value)
        decrypted = CryptoJS.enc.Utf8.stringify(bytes)
      } catch (e) {
        decrypted = '无效的Base64编码'
      }
      break
    default:
      decrypted = '未实现该算法的解密'
  }

  outputText.value = decrypted
}

// 新增输入输出互换函数
const swapInputs = () => {
  const temp = inputText.value
  inputText.value = outputText.value
  outputText.value = temp
}
</script>

<style scoped>
.encryptionBaseBox{
  height: 100%;
}

.ant-input :deep() {
  border-radius: 0 !important;
}

</style>
